#include "skops.h"
#include "kmglang_en.h"
#include "dfon_comdef.h"
#include "assign.h"
#include "rename.h"
#include "dfon_shared_if_voice_memo.h"
#include "actionops.h"

typedef boolean (*FilterFunc)(CatInfo *info, NodeGeneric *node);

static boolean IsUrl(CatInfo *info, NodeGeneric *node)
{
	if(node->type == NodeTypeAction)
	{
		NodeAction *action = (NodeAction*)node;
		if(action->id == IDS_GET_MORE_GRAPHICS || action->id == IDS_GET_MORE_RINGERS)
			return TRUE;
	}
	return FALSE;
}

static boolean IsFile(CatInfo *info, NodeGeneric *node)
{
	NodeFile *file = (NodeFile*)node;
	return node->type == NodeTypeFile && !STRENDS("noscreensaver.png", file->fi.szName);
}

static boolean IsThumbnailView(CatInfo *info, NodeGeneric *node)
{
	return info->viewType == ViewTypeThumbnail;
}

static boolean IsNotFullscr(CatInfo *info, NodeGeneric *node)
{
	return info->viewType != ViewTypeFullscr;
}

static boolean IsUnlocked(CatInfo *info, NodeGeneric *node)
{
	int i;
	NodeFile *nodeFile = (NodeFile*)node;
	char *lockedPaths[] = {
		"fs:/media/img/screensaver/default/",
		"fs:/media/img/wallpaper/default/",
		"fs:/media/snd/savedsnd/default/",
		"fs:/media/snd/ringer/default/",
		"fs:/media/img/picid/default/",
	};

	if(node->type != NodeTypeFile)
		return FALSE;

	for(i=0; i<ARRAY_SIZE(lockedPaths); i++)
	{
		if(STRBEGINS(lockedPaths[i], nodeFile->fi.szName))
			return FALSE;
	}

	//here we must check lock db
	return TRUE;
}

FilterFunc eraseRenameFilters[] = {IsFile, IsUnlocked, IsNotFullscr, NULL,};
FilterFunc assignFilters[] = {IsFile, NULL};
FilterFunc eraseAllFilters[] = {IsFile, IsNotFullscr, NULL};
FilterFunc goFilters[] = {IsUrl, NULL};
FilterFunc viewFilters[] = {IsFile, IsThumbnailView, IsNotFullscr, NULL};

typedef struct {
	uint16 sk;
	FilterFunc *filters;
} SkTableItem ;

SkTableItem browseSkTable[] =
{
	{IDS_GO_VMU, goFilters},
	{IDS_VIEW, viewFilters},
	{IDS_ASSIGN, assignFilters},
	{IDS_RENAME, eraseRenameFilters},
	{IDS_ERASE, eraseRenameFilters},
	{IDS_ERASEALL, eraseAllFilters},
	{IDS_DETAILS, assignFilters},
	{0,0}
};

SkTableItem chooseSkTable[] =
{
	{IDS_SELECT, assignFilters},
	{IDS_DETAILS, assignFilters},
	{0,0}
};

static void AddSK(uint16 **sk, int *count, uint16 skToAdd)
{
	uint16 *array = *sk;
	int newSize = *count + 1;

	array = REALLOC(array, newSize * sizeof(array[0]));
	array[newSize - 1] = skToAdd;

	*count = newSize;
	*sk = array;
}

void SKOps_GetList(CatInfo *catInfo, NodeGeneric *node, MGalleryMode mode, uint16 **sk, int *count)
{
	int i = 0;
	SkTableItem *skTable = browseSkTable;

	//if category don't have files it don't have options
	if(catInfo->pathList == NULL || node == NULL)
		return;

	if(mode == MGalleryModeChooseSound)
		skTable = chooseSkTable;

	for(i=0; skTable[i].sk != 0; i++)
	{
		int j;
		boolean filterRetval = TRUE;
		for(j = 0; skTable[i].filters[j] != 0; j++)
		{
			filterRetval = skTable[i].filters[j](catInfo, node);
			if(filterRetval == FALSE)
				break;
		}

		if(filterRetval != TRUE)
			continue;

		AddSK(sk, count, skTable[i].sk);
	}
}

static boolean Details_FormHandleEvent(void *data, AEEEvent evt, uint16 wParam, uint32 dwParam)
{
	HandlerDesc *hdesc = data;
	if(evt == EVT_KEY && wParam == AVK_SOFT1)
		return HANDLERDESC_Call(hdesc, EVT_FORM_CANCEL, 0, 0);
	return HANDLERDESC_Call(hdesc, evt, wParam, dwParam);
}

static void Details_FormCreate(MGallery *mgallery, NodeFile *node)
{
	HandlerDesc *hdesc = NULL;
	AECHAR resText[100] = L"";
	AECHAR text[1000] = L"";
	AECHAR *p = text;
	IForm *form = NULL;
	IWidget *textWidget = NULL;
	JulianType julDate;
	char *fname = NULL;

	//filename
	fname = STRRCHR(node->fi.szName, '/');
	if(fname){
		STRTOWSTR(fname + 1, text, sizeof(text));
		WSTRCAT(text, L"\n");
		p += WSTRLEN(p);
	}

	//size
	ISHELL_LoadResString(mgallery->shell, mgallery->resFileName, IDS_SIZE, resText, sizeof(resText));
	WSPRINTF(p, sizeof(text), L"%s %d kB\n", resText, node->fi.dwSize/1024);
	p += WSTRLEN(p);

	//resolution
	if(node->loadStage == ImageLoadSuccess)
	{
		WSPRINTF(p, sizeof(text), L"%dx%d\n", node->imageInfo.cx, node->imageInfo.cy);
		p += WSTRLEN(p);
	}

	//date
	GETJULIANDATE(node->fi.dwCreationDate, &julDate);
	ISHELL_LoadResString(mgallery->shell, mgallery->resFileName, IDS_DATE, resText, sizeof(resText));
	WSPRINTF(p, sizeof(text), L"%s %d/%d/%d\n", resText, julDate.wMonth, julDate.wDay, julDate.wYear);
	p += WSTRLEN(p);

	//free space
	ISHELL_LoadResString(mgallery->shell, mgallery->resFileName, IDS_AVAILABLE, resText, sizeof(resText));
	WSPRINTF(p, sizeof(text), L"%s\n", resText);
	p += WSTRLEN(p);
	ISHELL_LoadResString(mgallery->shell, mgallery->resFileName, IDS_ONPHONE, resText, sizeof(resText));
	WSPRINTF(p, sizeof(text), L"%s %u kB\n", resText, GETFSFREE(NULL) / 1024);
	p += WSTRLEN(p);

	//loacked/unlocked
	if(IsUnlocked(NULL, (NodeGeneric*)node) == FALSE){
		ISHELL_LoadResString(mgallery->shell, mgallery->resFileName, IDS_LOCKED, resText, sizeof(resText));
		WSPRINTF(p, sizeof(text), L"%s\n", resText);
		p += WSTRLEN(p);
	}

	//create form
	hdesc = MALLOCREC(HandlerDesc);
	ISHELL_CreateInstance(mgallery->shell, AEECLSID_FORM, (void**)&form);
	ISHELL_CreateInstance(mgallery->shell, AEECLSID_STATICWIDGET, (void**)&textWidget);

	IFORM_SetWidget(form, WID_FORM, textWidget);
	IWIDGET_SetText(textWidget, WSTRDUP(text), TRUE);
	IWIDGET_SetFlags(textWidget, IDF_ALIGN_TOP|IDF_ALIGN_LEFT|SWF_WRAPTEXT);
	IWIDGET_SetFGColor(textWidget, RGB_WHITE);
	IFORM_SetThemeBaseName(form, PTL_NORMALFORM_BASE_NAME);

	HANDLERDESC_Init(hdesc, Details_FormHandleEvent, hdesc, FREE);
	IFORM_SetHandler(form, hdesc);

	IPTLAYER_FormSetTitle(mgallery->ptl, mgallery->rf, form, mgallery->resFileName, IDS_DETAILS);
	IPTLAYER_FormSetSoftKeys(mgallery->ptl, mgallery->rf, form, mgallery->resFileName, IDS_OK, 0);
	
	IROOTFORM_PushForm(mgallery->rf, form);
	
	RELEASEIF(form);
	RELEASEIF(textWidget);
}

typedef struct 
{
	MGallery *mgallery;
	NodeFile * file;
	IVectorModel *model;
	IPTLayer *ptl;
	boolean eraseAll;
} EraseFileCtx ;

void EraseCB(void *userData, int sk)
{
	EraseFileCtx *ctx = userData;

	if(sk == IDS_YES && ctx->file && ctx->file->base.type == NodeTypeFile)
	{
		IFileMgr *fmgr = NULL;
		AlertDesc alert = {0, IDS_ERASED, IDS_MSG_ERASE_SUCCESS, 0};
		ISHELL_CreateInstance(ctx->mgallery->shell, AEECLSID_FILEMGR, (void**)&fmgr);
		if(fmgr)
		{
			if(!ctx->eraseAll){
				IFILEMGR_Remove(fmgr, ctx->file->fi.szName);
				IVECTORMODEL_DeleteAt(ctx->model, ctx->file->base.index);
			}
			alert.resName = ctx->mgallery->resFileName;
			IPTLAYER_MakeAlert(ctx->mgallery->ptl, &alert, NULL, NULL);
		}
	}

	FREEIF(userData);
}

boolean SKOps_HandleSK(MGallery *mgallery, IVectorModel *model, CatInfo *catInfo, NodeGeneric *node, uint16 sk)
{
	boolean retVal = TRUE;
	AlertDesc alert = {0};
	EraseFileCtx *eraseCtx = NULL;
	UTIL_HISTORY_DATA histData;

	alert.resName = mgallery->resFileName;

	switch(sk)
	{
	case IDS_ERASE:
	case IDS_ERASEALL:
		//alloc and init ctx
		eraseCtx = MALLOCREC(EraseFileCtx);
		eraseCtx->file = (NodeFile*)node;
		eraseCtx->mgallery = mgallery;
		eraseCtx->model = model;
		eraseCtx->eraseAll = (sk == IDS_ERASEALL);

		alert.icon = IPTLAYER_ALERTWIN_ICONQUESTION;
		alert.title = IDS_QUESTION;
		alert.text = eraseCtx->eraseAll ? IDS_MSG_DELETEALL_CONFIRM : IDS_MSG_DELETE_CONFIRM_VMU;
		alert.lsk = IDS_YES;
		alert.rsk = IDS_NO;
		alert.timeout = -1;
		IPTLAYER_MakeAlert(mgallery->ptl, &alert, EraseCB, eraseCtx);
		break;
	case IDS_GO_VMU:
		ActionOps_HandleAction(mgallery,catInfo,(NodeAction*)node);
		break;
	case IDS_RENAME:
		Rename_Create(mgallery, (NodeFile*)node);
		break;
	case IDS_DETAILS:
		Details_FormCreate(mgallery, (NodeFile*)node);
		break;
	case IDS_ASSIGN:
		Assign_Create(mgallery, (NodeFile*)node);
		break;
	case IDS_SELECT:
		STRCPY(mgallery->outFileName, ((NodeFile*)node)->fi.szName);
		*mgallery->outValue = SUCCESS;
		ISHELL_CloseApplet(mgallery->shell, FALSE);
		break;
	case IDS_RECORDNEW:
		ZEROAT(&histData);
		histData.sender = AEECLSID_MG;
		histData.target = AEECLSID_DIFFON_VOICEMEMO;
		histData.IFSymbol = DFON_VOICEMEMO_IF_TYPE_MYSTUFF_RECORD_TERMINATE;
		DFON_IUTILLIB_SetHistory(mgallery->utils, DFON_HISTORY_VOICEMEMO, &histData);
		ISHELL_StartApplet(mgallery->shell, AEECLSID_DIFFON_VOICEMEMO);
		break;
	default:
		retVal = FALSE;
		break;
	}

	return retVal;
}